package com.pennywise.service;

import com.pennywise.common.exception.BusinessException;
import com.pennywise.model.SavingPlan;
import com.pennywise.model.Transaction;
import com.pennywise.model.UserProfile;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class SavingPlanService {
    
    private final UserProfileService userProfileService;
    private final TransactionService transactionService;
    private final ReminderService reminderService;
    
    /**
     * 计算并更新存钱计划
     */
    public SavingPlan calculateSavingPlan() {
        UserProfile profile = userProfileService.getCurrentProfile();
        if (profile == null) {
            throw new BusinessException("请先设置个人信息");
        }
        
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime yearEnd = LocalDateTime.of(now.getYear(), 12, 31, 23, 59, 59);
        long remainingMonths = ChronoUnit.MONTHS.between(now, yearEnd) + 1;
        
        // 计算当前已存金额（收入-支出）
        BigDecimal totalIncome = calculateTotalByType("收入", now.withDayOfYear(1), now);
        BigDecimal totalExpense = calculateTotalByType("支出", now.withDayOfYear(1), now);
        BigDecimal currentSaved = totalIncome.subtract(totalExpense);
        
        // 计算每月需要存的金额
        BigDecimal remainingToSave = profile.getYearEndTarget().subtract(currentSaved);
        BigDecimal monthlySavingTarget = remainingToSave.divide(BigDecimal.valueOf(remainingMonths), 2, RoundingMode.CEILING);
        
        SavingPlan plan = new SavingPlan();
        plan.setYearEndTarget(profile.getYearEndTarget());
        plan.setCurrentSaved(currentSaved);
        plan.setMonthlySavingTarget(monthlySavingTarget);
        plan.setStartTime(now.withDayOfYear(1));
        plan.setEndTime(yearEnd);
        
        log.info("计算存钱计划: 年度目标={}, 当前已存={}, 每月需存={}", 
                plan.getYearEndTarget(), plan.getCurrentSaved(), plan.getMonthlySavingTarget());
        
        return plan;
    }
    
    /**
     * 分析本月消费情况并生成建议
     */
    public String analyzeMonthlySpending() {
        UserProfile profile = userProfileService.getCurrentProfile();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime monthStart = now.withDayOfMonth(1).withHour(0).withMinute(0);
        
        // 获取本月消费数据
        BigDecimal monthlyExpense = calculateTotalByType("支出", monthStart, now);
        BigDecimal monthlySalary = profile.getMonthlySalary();
        SavingPlan plan = calculateSavingPlan();
        
        // 生成分析和建议
        StringBuilder analysis = new StringBuilder();
        analysis.append(String.format("本月消费情况分析：\n"));
        analysis.append(String.format("1. 月收入：%.2f元\n", monthlySalary));
        analysis.append(String.format("2. 当前消费：%.2f元 (%.1f%%)\n", 
                monthlyExpense, monthlyExpense.divide(monthlySalary, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100))));
        analysis.append(String.format("3. 建议每月存款：%.2f元\n", plan.getMonthlySavingTarget()));
        
        BigDecimal remainingBudget = monthlySalary.subtract(monthlyExpense).subtract(plan.getMonthlySavingTarget());
        if (remainingBudget.compareTo(BigDecimal.ZERO) < 0) {
            analysis.append("警告：当前消费已超出预算，建议立即控制支出！\n");
            createSpendingWarningReminder(remainingBudget.abs());
        } else {
            analysis.append(String.format("4. 本月还可支配：%.2f元\n", remainingBudget));
        }
        
        return analysis.toString();
    }
    
    /**
     * 检查是否需要存钱提醒
     */
    @Scheduled(cron = "0 0 10 * * ?") // 每天上午10点检查
    public void checkSavingReminder() {
        UserProfile profile = userProfileService.getCurrentProfile();
        LocalDateTime now = LocalDateTime.now();
        
        // 如果今天是发薪日，创建存钱提醒
        if (now.getDayOfMonth() == profile.getSalaryDay()) {
            SavingPlan plan = calculateSavingPlan();
            createSavingReminder(plan.getMonthlySavingTarget());
        }
    }
    
    private BigDecimal calculateTotalByType(String type, LocalDateTime startTime, LocalDateTime endTime) {
        List<Transaction> transactions = transactionService.getTransactionsByTimeRange(startTime, endTime);
        return transactions.stream()
                .filter(t -> t.getType().equals(type))
                .map(Transaction::getAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    
    private void createSavingReminder(BigDecimal amount) {
        String title = "存钱提醒";
        String content = String.format("今天是发薪日，请记得存入%.2f元以实现年度存款目标。", amount);
        reminderService.addReminder(title, content, LocalDateTime.now().plusHours(1));
    }
    
    private void createSpendingWarningReminder(BigDecimal overAmount) {
        String title = "消费预警";
        String content = String.format("您已超出本月预算%.2f元，请注意控制支出！", overAmount);
        reminderService.addReminder(title, content, LocalDateTime.now());
    }
} 